const express = require('express');
const { body, query, param, validationResult } = require('express-validator');
const multer = require('multer');
const path = require('path');
const { User } = require('../models');
const { authenticate, authorize, checkResourceOwnership } = require('../middleware/auth');
const { AppError, ValidationError } = require('../middleware/errorHandler');
const config = require('../config/config');
const logger = require('../config/logger');
const redis = require('../config/redis');

const router = express.Router();

// 文件上传配置
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, path.join(process.cwd(), 'uploads/avatars'));
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, `avatar-${req.user.id}-${uniqueSuffix}${path.extname(file.originalname)}`);
  }
});

const upload = multer({
  storage,
  limits: {
    fileSize: config.upload.maxFileSize,
    files: 1
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
    if (allowedTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new AppError('只允许上传图片文件', 400), false);
    }
  }
});

// 验证规则
const updateProfileValidation = [
  body('realName')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('真实姓名长度必须在1-50个字符之间'),
  
  body('nickname')
    .optional()
    .isLength({ min: 1, max: 50 })
    .withMessage('昵称长度必须在1-50个字符之间'),
  
  body('gender')
    .optional()
    .isIn(['male', 'female', 'other'])
    .withMessage('性别值无效'),
  
  body('birthday')
    .optional()
    .isISO8601()
    .withMessage('生日格式无效'),
  
  body('bio')
    .optional()
    .isLength({ max: 500 })
    .withMessage('个人简介不能超过500个字符'),
  
  body('phone')
    .optional()
    .matches(/^[1][3-9]\d{9}$/)
    .withMessage('请输入有效的手机号码')
    .custom(async (value, { req }) => {
      if (value) {
        const user = await User.findOne({ 
          where: { 
            phone: value,
            id: { [require('sequelize').Op.ne]: req.user.id }
          }
        });
        if (user) {
          throw new Error('手机号已被其他用户使用');
        }
      }
      return true;
    })
];

const updatePreferencesValidation = [
  body('preferences')
    .isObject()
    .withMessage('偏好设置必须是对象格式'),
  
  body('preferences.language')
    .optional()
    .isIn(['zh-CN', 'en-US', 'ja-JP'])
    .withMessage('语言设置无效'),
  
  body('preferences.timezone')
    .optional()
    .isString()
    .withMessage('时区设置无效'),
  
  body('preferences.theme')
    .optional()
    .isIn(['light', 'dark', 'auto'])
    .withMessage('主题设置无效')
];

const getUsersValidation = [
  query('page')
    .optional()
    .isInt({ min: 1 })
    .withMessage('页码必须是正整数'),
  
  query('limit')
    .optional()
    .isInt({ min: 1, max: 100 })
    .withMessage('每页数量必须在1-100之间'),
  
  query('role')
    .optional()
    .isIn(['student', 'teacher', 'admin', 'super_admin'])
    .withMessage('角色值无效'),
  
  query('status')
    .optional()
    .isIn(['active', 'inactive', 'suspended', 'deleted'])
    .withMessage('状态值无效'),
  
  query('search')
    .optional()
    .isLength({ min: 1, max: 100 })
    .withMessage('搜索关键词长度必须在1-100个字符之间')
];

const updateUserValidation = [
  param('id')
    .isUUID()
    .withMessage('用户ID格式无效'),
  
  body('role')
    .optional()
    .isIn(['student', 'teacher', 'admin'])
    .withMessage('角色值无效'),
  
  body('status')
    .optional()
    .isIn(['active', 'inactive', 'suspended'])
    .withMessage('状态值无效'),
  
  body('permissions')
    .optional()
    .isArray()
    .withMessage('权限必须是数组格式')
];

// 工具函数
const handleValidationErrors = (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    const errorMessages = errors.array().map(error => error.msg);
    throw new ValidationError('验证失败', errorMessages);
  }
  next();
};

const buildUserQuery = (queryParams) => {
  const { role, status, search, emailVerified } = queryParams;
  const where = {};
  
  if (role) {
    where.role = role;
  }
  
  if (status) {
    where.status = status;
  }
  
  if (emailVerified !== undefined) {
    where.emailVerified = emailVerified === 'true';
  }
  
  if (search) {
    const { Op } = require('sequelize');
    where[Op.or] = [
      { username: { [Op.like]: `%${search}%` } },
      { email: { [Op.like]: `%${search}%` } },
      { realName: { [Op.like]: `%${search}%` } },
      { nickname: { [Op.like]: `%${search}%` } }
    ];
  }
  
  return where;
};

// 路由处理函数

/**
 * @route   GET /api/users
 * @desc    获取用户列表
 * @access  Private (Admin)
 */
router.get('/', authenticate, authorize(['admin', 'super_admin']), getUsersValidation, handleValidationErrors, async (req, res, next) => {
  try {
    const {
      page = 1,
      limit = 20,
      sortBy = 'createdAt',
      sortOrder = 'DESC'
    } = req.query;
    
    const offset = (page - 1) * limit;
    const where = buildUserQuery(req.query);
    
    const { count, rows: users } = await User.findAndCountAll({
      where,
      limit: parseInt(limit),
      offset,
      order: [[sortBy, sortOrder.toUpperCase()]],
      attributes: { exclude: ['password'] }
    });
    
    const totalPages = Math.ceil(count / limit);
    
    res.json({
      success: true,
      data: {
        users,
        pagination: {
          currentPage: parseInt(page),
          totalPages,
          totalItems: count,
          itemsPerPage: parseInt(limit),
          hasNextPage: page < totalPages,
          hasPrevPage: page > 1
        }
      }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   GET /api/users/stats
 * @desc    获取用户统计信息
 * @access  Private (Admin)
 */
router.get('/stats', authenticate, authorize(['admin', 'super_admin']), async (req, res, next) => {
  try {
    const stats = {
      total: await User.count(),
      active: await User.count({ where: { status: 'active' } }),
      inactive: await User.count({ where: { status: 'inactive' } }),
      suspended: await User.count({ where: { status: 'suspended' } }),
      students: await User.count({ where: { role: 'student' } }),
      teachers: await User.count({ where: { role: 'teacher' } }),
      admins: await User.count({ where: { role: 'admin' } }),
      emailVerified: await User.count({ where: { emailVerified: true } }),
      emailUnverified: await User.count({ where: { emailVerified: false } })
    };
    
    // 获取最近注册用户数（最近7天）
    const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
    stats.recentRegistrations = await User.count({
      where: {
        createdAt: {
          [require('sequelize').Op.gte]: sevenDaysAgo
        }
      }
    });
    
    res.json({
      success: true,
      data: { stats }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   GET /api/users/:id
 * @desc    获取指定用户信息
 * @access  Private (Admin or Self)
 */
router.get('/:id', authenticate, param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 检查权限：管理员可以查看任何用户，普通用户只能查看自己
    if (currentUser.id !== id && !['admin', 'super_admin'].includes(currentUser.role)) {
      throw new AppError('无权限访问此用户信息', 403);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    res.json({
      success: true,
      data: { user: user.toJSON() }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   PUT /api/users/:id/profile
 * @desc    更新用户资料
 * @access  Private (Self or Admin)
 */
router.put('/:id/profile', authenticate, param('id').isUUID().withMessage('用户ID格式无效'), updateProfileValidation, handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 检查权限
    if (currentUser.id !== id && !['admin', 'super_admin'].includes(currentUser.role)) {
      throw new AppError('无权限修改此用户信息', 403);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    const { realName, nickname, gender, birthday, bio, phone } = req.body;
    
    await user.update({
      realName,
      nickname,
      gender,
      birthday,
      bio,
      phone
    });
    
    logger.request('用户资料更新', {
      userId: user.id,
      updatedBy: currentUser.id,
      changes: Object.keys(req.body),
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '用户资料更新成功',
      data: { user: user.toJSON() }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   PUT /api/users/:id/preferences
 * @desc    更新用户偏好设置
 * @access  Private (Self)
 */
router.put('/:id/preferences', authenticate, param('id').isUUID().withMessage('用户ID格式无效'), updatePreferencesValidation, handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 只能修改自己的偏好设置
    if (currentUser.id !== id) {
      throw new AppError('只能修改自己的偏好设置', 403);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    const { preferences } = req.body;
    
    // 合并现有偏好设置
    const updatedPreferences = {
      ...user.preferences,
      ...preferences
    };
    
    await user.update({ preferences: updatedPreferences });
    
    res.json({
      success: true,
      message: '偏好设置更新成功',
      data: { preferences: updatedPreferences }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   POST /api/users/:id/avatar
 * @desc    上传用户头像
 * @access  Private (Self or Admin)
 */
router.post('/:id/avatar', authenticate, param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, upload.single('avatar'), async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 检查权限
    if (currentUser.id !== id && !['admin', 'super_admin'].includes(currentUser.role)) {
      throw new AppError('无权限修改此用户头像', 403);
    }
    
    if (!req.file) {
      throw new AppError('请选择要上传的头像文件', 400);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    // 构建头像URL
    const avatarUrl = `/uploads/avatars/${req.file.filename}`;
    
    await user.update({ avatar: avatarUrl });
    
    logger.request('用户头像更新', {
      userId: user.id,
      updatedBy: currentUser.id,
      avatarUrl,
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '头像上传成功',
      data: {
        avatar: avatarUrl
      }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   PUT /api/users/:id
 * @desc    更新用户信息（管理员）
 * @access  Private (Admin)
 */
router.put('/:id', authenticate, authorize(['admin', 'super_admin']), updateUserValidation, handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    // 超级管理员不能被普通管理员修改
    if (user.role === 'super_admin' && currentUser.role !== 'super_admin') {
      throw new AppError('无权限修改超级管理员', 403);
    }
    
    const { role, status, permissions } = req.body;
    const updates = {};
    
    if (role !== undefined) {
      // 只有超级管理员可以设置管理员角色
      if (role === 'admin' && currentUser.role !== 'super_admin') {
        throw new AppError('只有超级管理员可以设置管理员角色', 403);
      }
      updates.role = role;
    }
    
    if (status !== undefined) {
      updates.status = status;
    }
    
    if (permissions !== undefined) {
      updates.permissions = permissions;
    }
    
    await user.update(updates);
    
    logger.request('用户信息更新（管理员操作）', {
      userId: user.id,
      updatedBy: currentUser.id,
      changes: Object.keys(updates),
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '用户信息更新成功',
      data: { user: user.toJSON() }
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   DELETE /api/users/:id
 * @desc    删除用户
 * @access  Private (Super Admin)
 */
router.delete('/:id', authenticate, authorize(['super_admin']), param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 不能删除自己
    if (currentUser.id === id) {
      throw new AppError('不能删除自己的账户', 400);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    // 软删除
    await user.destroy();
    
    // 清除用户的所有会话
    await redis.del(`refresh_token:${id}`);
    
    logger.request('用户删除', {
      userId: user.id,
      deletedBy: currentUser.id,
      username: user.username,
      email: user.email,
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '用户删除成功'
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   POST /api/users/:id/suspend
 * @desc    暂停用户
 * @access  Private (Admin)
 */
router.post('/:id/suspend', authenticate, authorize(['admin', 'super_admin']), param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    const { reason } = req.body;
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    // 超级管理员不能被暂停
    if (user.role === 'super_admin') {
      throw new AppError('不能暂停超级管理员', 403);
    }
    
    // 不能暂停自己
    if (currentUser.id === id) {
      throw new AppError('不能暂停自己的账户', 400);
    }
    
    await user.update({ status: 'suspended' });
    
    // 清除用户的所有会话
    await redis.del(`refresh_token:${id}`);
    
    logger.request('用户暂停', {
      userId: user.id,
      suspendedBy: currentUser.id,
      reason,
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '用户已暂停'
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   POST /api/users/:id/activate
 * @desc    激活用户
 * @access  Private (Admin)
 */
router.post('/:id/activate', authenticate, authorize(['admin', 'super_admin']), param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    await user.update({ status: 'active' });
    
    logger.request('用户激活', {
      userId: user.id,
      activatedBy: currentUser.id,
      ip: req.ip
    });
    
    res.json({
      success: true,
      message: '用户已激活'
    });
  } catch (error) {
    next(error);
  }
});

/**
 * @route   GET /api/users/:id/activity
 * @desc    获取用户活动记录
 * @access  Private (Self or Admin)
 */
router.get('/:id/activity', authenticate, param('id').isUUID().withMessage('用户ID格式无效'), handleValidationErrors, async (req, res, next) => {
  try {
    const { id } = req.params;
    const currentUser = req.user;
    
    // 检查权限
    if (currentUser.id !== id && !['admin', 'super_admin'].includes(currentUser.role)) {
      throw new AppError('无权限查看此用户活动', 403);
    }
    
    const user = await User.findByPk(id);
    if (!user) {
      throw new AppError('用户不存在', 404);
    }
    
    // 这里可以实现用户活动记录的查询
    // 暂时返回基本信息
    const activity = {
      lastLoginAt: user.lastLoginAt,
      lastLoginIp: user.lastLoginIp,
      totalStudyTime: user.totalStudyTime,
      totalCourses: user.totalCourses,
      completedCourses: user.completedCourses,
      totalExams: user.totalExams,
      passedExams: user.passedExams,
      totalCertificates: user.totalCertificates
    };
    
    res.json({
      success: true,
      data: { activity }
    });
  } catch (error) {
    next(error);
  }
});

module.exports = router;